package com.jthinker;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.apache.commons.lang3.SystemUtils.FILE_ENCODING;
import static org.apache.commons.lang3.SystemUtils.LINE_SEPARATOR;

/**
 * User: Gang Chen
 * Date: 2015/3/27 22:41
 */
public class Host
{

    private static final Properties PROPS = new Properties();

    private static final String UA;

    private static final String URL;

    private static final String REGEX_IP = "((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-4]|1\\d{0,2}|[1-9]\\d|[1-9])";

    private static final String HOST_PATH;

    static
    {
        try
        {
            PROPS.load(Host.class.getResourceAsStream("/config.properties"));
            URL = PROPS.getProperty("url");
            UA = PROPS.getProperty("ua");

            if (SystemUtils.IS_OS_WINDOWS)
            {
                HOST_PATH = "C:/Windows/System32/drivers/etc/hosts";
            }
            else
            {
                HOST_PATH = "/etc/hosts";
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    private static String fetch() throws IOException
    {
        Document doc = Jsoup.connect(URL).userAgent(UA).get();
        Elements pre = doc.getElementsByTag("pre");
        String html = pre.html();
        return html;
    }

    private static String parse(String html)
    {
        StringBuilder hosts = new StringBuilder();
        hosts.append("#### Google host ").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())).append(" ####");

        Pattern pattern = Pattern.compile(REGEX_IP);
        Matcher matcher;

        String[] lines = StringUtils.split(html, LINE_SEPARATOR);
        for (String line : lines)
        {
            matcher = pattern.matcher(line);
            if (matcher.find())
            {
                hosts.append(LINE_SEPARATOR);
                hosts.append(line);
            }
        }

        hosts.append(LINE_SEPARATOR).append("#### Google host end").append(" ####");
        return hosts.toString();
    }

    private static String readHost()
    {
        File hostFile = new File(HOST_PATH);

        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;

        try
        {
            inputStreamReader = new InputStreamReader(new FileInputStream(hostFile), FILE_ENCODING);
            bufferedReader = new BufferedReader(inputStreamReader);
            FileUtils.copyFile(hostFile, new File(hostFile.getAbsolutePath() + ".bak"));
            StringBuilder txt = new StringBuilder();
            boolean isIn = false;
            String line;
            while ((line = bufferedReader.readLine()) != null)
            {
                if (line.startsWith("####") && !isIn)
                {
                    isIn = true;
                }
                else if (line.startsWith("####") && isIn)
                {
                    isIn = false;
                }
                else if (!isIn)
                {
                    txt.append(line).append(LINE_SEPARATOR);
                }
            }
            return txt.toString();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            IOUtils.closeQuietly(bufferedReader);
            IOUtils.closeQuietly(inputStreamReader);
        }

        return null;
    }

    private static void writeHost(String txt) throws IOException
    {
        FileUtils.write(new File(HOST_PATH), txt, FILE_ENCODING);
    }

    public static void main(String[] args) throws IOException
    {
        String html = fetch();
        String googleHost = parse(html);
        String host = readHost();
        String hostNew = host + googleHost;
        writeHost(hostNew);

        System.out.println(hostNew);
    }
}
